package com.fyl.log.aop;


import com.fyl.log.anno.AsyncLog;
import com.fyl.log.dto.LogDTO;
import com.fyl.log.service.AsyncLogService;
import com.fyl.utils.IPUtils;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;

public class AsyncLogMethodInterceptor implements MethodInterceptor {

    @Lazy
    @Autowired
    AsyncLogService asyncLogService;

    @Autowired
    HttpServletRequest request;

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {

        long beginTime = System.currentTimeMillis();
        // 执行方法
        Object result = invocation.proceed();
        // 执行时长(毫秒)
        long time = System.currentTimeMillis() - beginTime;

        LogDTO logDTO = new LogDTO();
        String className = invocation.getThis().getClass().getName();
        Method method = invocation.getMethod();
        String methodName = method.getName();
        // 请求的方法名
        logDTO.setMethod(className + "." + methodName + "()");

        AsyncLog sysLog = AnnotationUtils.getAnnotation(method, AsyncLog.class);
        if (sysLog != null) {
            // 注解上的描述
            logDTO.setOperation(sysLog.action());
        }
        // 请求的参数
        Object[] arguments = invocation.getArguments();
        ArrayList<Object> params = new ArrayList<>();
        for (int i = 0; i < arguments.length; i++) {
            Object arg = arguments[i];
            if (arg instanceof HttpServletRequest || arg instanceof HttpServletResponse) {
                continue;
            }
            if (arg instanceof MultipartFile) {
                MultipartFile file = (MultipartFile) arg;
                params.add(file.getOriginalFilename());
            } else if (arg instanceof MultipartFile[]) {
                MultipartFile[] files = (MultipartFile[]) arg;
                Arrays.stream(files).forEach(el -> params.add(el.getOriginalFilename()));
            } else {
                params.add(arg);
            }
        }
        logDTO.setParams(params);
        // 设置IP地址
        logDTO.setIp(IPUtils.getIpAddr(request));
        logDTO.setPeriod((int) time);
        // 系统当前时间
        logDTO.setTimeAt(System.currentTimeMillis());
        logDTO.setResult(result);
        LogDTO.Operator operator = asyncLogService.getOperator();
        logDTO.setOperator(operator);
        // 保存系统日志
        asyncLogService.asyncSave(logDTO);
        return result;
    }

}
